<?php

namespace App;

use App\Helpers\ApiAdminLogTrait;
use App\Helpers\ApiCurdTrait;
use App\Helpers\ApiListTrait;
use App\Helpers\ApiResponseTrait;
use App\Helpers\ExcelExportTrait;
use Illuminate\Support\Facades\DB;

class BaseRepository
{
    use ApiResponseTrait,ApiAdminLogTrait,ApiListTrait,ApiCurdTrait,ExcelExportTrait;

    //模型名称
    protected $modelName;

    //请求的参数
    public $request;

    //登录的用户
    public $loginUser;

    //错误消息
    public $error;

    //挂载数据
    protected $propsData;

    //是否自动加载创建人、更新人名称
    protected $appendCreatorAndUpdater = false;

    //是否自动加载创建人、更新人id
    protected $appendUserId = false;

    //基础控制器方法权限验证
    protected $allowApiMethod = ['index','show','store','update','destroy','destroyBatch'];

    //检查权限（可自定义）
    protected function checkAuth($action)
    {
        if(!in_array($action,$this->allowApiMethod)) {
            $this->error = $this->noPower();
            return false;
        }
        return true;
    }
    protected function isSuper()
    {
        return $this->loginUser?($this->loginUser->userType=="super"?true:false):false;
    }

    //创建查询模型
    protected function query()
    {
        return $this->model();
    }

    //实例化模型
    protected function model($id = false)
    {
        return $id ? $this->query()->find($id) : new $this->modelName;
    }

    //列表初始化查询模型
    protected function initListQuery($query)
    {
        return $query;
    }

    //模型字段
    protected function modelColumns()
    {
        return $this->model()->tableColumns();
    }

    //列表
    public function index($request)
    {
        if(!$this->checkAuth('index')) {
            return $this->error;
        }

        $param = $request->input('_param');

        $query = $this->initListQuery($this->query());

        $this->build($query,$param);

        $items = $this->getListItems();

        $this->saveIndexLog($request);

        return $this->pages($items,$this->totalCount,json_decode($param));
    }

    protected function simpleListQuery()
    {
        return $this->initListQuery(DB::table($this->query()->getTable())->whereNull('deleted_at'));
    }

    public function simpleList($request,$id)
    {
        if ($id!==false){
            $simpleListFiled = $this->simpleListFiled();
            $query = $this->simpleListQuery();
            if ($simpleListFiled) $query = $query->select($simpleListFiled);
            $item = $query->find($id);
            return $this->success($item);
        }
        if(!$this->checkAuth('simpleList')) {
            return $this->error;
        }

        $param = $request->input('_param');

        $this->build($this->simpleListQuery(),$param);

        $items = $this->getSimpleListItems();

        $this->saveIndexLog($request);

        return $this->pages($items,$this->totalCount,json_decode($param));
    }

    //新建
    public function store($request)
    {
        if(!$this->checkAuth('store')) {
            return $this->error;
        }

        if(!$this->storeValidate()) {
            return $this->failed($this->error);
        }

        $fillData = $this->getStoreFillData();

        $model = $this->model()->fill($fillData);

        if($model->beforeSave($this->request->all()) && $model->save() && $model->afterSave()){

            $this->afterStore($model);
            $this->commonSave($model);

            $respond = $this->getStoreRespondData($model);

            $this->saveStoreLog($request,$model);

            return $this->success($respond);
        }

        return $this->failed('创建失败');
    }

    //显示
    public function show($id)
    {
        if(!$this->checkAuth('show')) {
            return $this->error;
        }

        if($model = $this->model($id)){

            $respond = $this->getShowRespondData($model);

            $this->saveShowLog($id);

            return $this->success($respond);
        }

        return $this->notFond();
    }

    protected function simpleListFiled()
    {
        return [];
    }

    //更新
    public function update($request, $id)
    {
        if(!$this->checkAuth('update')) {
            return $this->error;
        }

        if(!$this->updateValidate($id)) {
            return $this->failed($this->error);
        }

        $fillData = $this->getUpdateFillData();

        $model = $this->model($id)->fill($fillData);

        $originalModel = $model->getOriginal();

        if($model->beforeSave($this->request->all()) && $model->save() && $model->afterSave()){

            $this->afterUpdate($model);
            $this->commonSave($model);

            $respond = $this->getUpdateRespondData($model);

            $this->saveUpdateLog($model,$originalModel,$request,$id);
            return $this->success($respond);
        }

        return $this->failed('');
    }

    //删除
    public function destroy($id)
    {
        if(!$this->checkAuth('destroy')) {
            return $this->error;
        }

        if(!$this->destroyValidate($id)) {
            return $this->failed($this->error);
        }

        $old_model = $model = $this->model($id);

        if(!$model) return $this->notFond();

        if($this->delete($model)) {

            $this->afterDestroy($old_model);

            $this->saveDestroyLog($old_model,$id);

            return $this->message('删除成功');
        }

        return $this->failed('删除失败');
    }


    //批量删除
    public function destroyBatch($request)
    {
        if(!$this->checkAuth('destroyBatch')) {
            return $this->error;
        }

        if(!$this->destroyBatchValidate()) {
            return $this->failed($this->error);
        }

        $ids = $request->input('ids');
        if(is_string($ids)) $ids = explode(',',$ids);

        $i = 0;
        $totalCount = count($ids);
        $errors = [];

        foreach ($ids as $id) {
            if(!$this->destroyValidate($id)) {
                $errors[] = '#'.$id. ' '.$this->error;
                continue;
            }

            $old_model = $model = $this->model($id);

            if($model) {
                if($this->delete($model)) {
                    $this->afterDestroy($old_model);
                    $i++;
                }else{
                    $errors[] = '#'.$id.' '.$this->error;
                }
            }else{
                $errors[] = '#'.$id. ' not found';
            }
        }

        $this->saveDestroyBatchLog($request);

        $data = [
            'successTotal' => $i,
            'totalCount' => $totalCount,
            'errors' => $errors
        ];

        if($i == 0) {
            return $this->errorWithData($data);
        }else{
            return $this->success($data);
        }
    }

    //到出
    public function export()
    {
        return $this->noPower();
    }
}
